package cn.com.greatwall.flowable.service.impl;

import java.util.Map;
import java.util.Set;

import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.com.greatwall.common.exception.EntityExistException;
import cn.com.greatwall.common.utils.PageUtil;
import cn.com.greatwall.common.utils.QueryHelp;
import cn.com.greatwall.common.utils.RedisUtils;
import cn.com.greatwall.common.utils.ValidationUtil;
import cn.com.greatwall.flowable.domain.Form;
import cn.com.greatwall.flowable.repository.FormRepository;
import cn.com.greatwall.flowable.service.FormService;
import cn.com.greatwall.flowable.service.dto.criteria.FormQueryCriteria;
import cn.com.greatwall.flowable.service.mapstruct.FormMapper;
import lombok.RequiredArgsConstructor;

/**
 * @Author herw
 * @Time 2020-09-01 10:14:29
 * @Version 1.0
 * @Description: TODO(用一句话描述该文件做什么)
 */
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "form")
public class FormServiceImpl implements FormService {
    private final FormRepository formRepository;
    private final FormMapper formMapper;
    private final RedisUtils redisUtils;

    @Override
    public Map<String, Object> queryAll(FormQueryCriteria criteria, Pageable pageable) {
        // TODO Auto-generated method stub
        Page<Form> page = formRepository.findAll(
                (root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder),
                pageable);
        return PageUtil.toPage(page.map(formMapper::toDto).getContent(), page.getTotalElements());
    }

    @Override
    public void create(Form resources) {
        Form form = formRepository.findByFormName(resources.getFormName());
        if (form != null) {
            throw new EntityExistException(Form.class, "formName", resources.getFormName());
        }
        formRepository.save(resources);
    }

    @Override
    @CacheEvict("'id:' + #p0.id")
    @Transactional(rollbackFor = Exception.class)
    public void update(Form resources) {
        Form form = formRepository.findById(resources.getId()).orElseGet(Form::new);
        Form oldName = formRepository.findByFormName(resources.getFormName());
        if (oldName != null && !oldName.getId().equals(resources.getId())) {
            throw new EntityExistException(Form.class, "formName", resources.getFormName());
        }
        Form oldKey = formRepository.findByFormKey(resources.getFormKey());
        if (oldKey != null && !oldKey.getId().equals(resources.getId())) {
            throw new EntityExistException(Form.class, "formKey", resources.getFormKey());
        }
        ValidationUtil.isNull(form.getId(), "Form", "id", resources.getId());
        resources.setId(form.getId());
        formRepository.save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Set<Long> ids) {
        formRepository.deleteAllByIdIn(ids);
        // 删除缓存
        redisUtils.delByKeys("form::id:", ids);
    }

    @Override
    public Form getByFormKey(String formKey) {
        Form form = formRepository.findByFormKey(formKey);
        return form;
    }
}
